<?php
/** 
 * @package AMFramework
 * @subpackage Core
 * @author Marcu Alexandru
 * @version 1.0 $Build 305b  
 */
defined('_INDEX') or die('Restricted');

class Amfw_Table extends Amfw_Object
{
	protected $_db;
	protected $_table;
	protected $_pk;
	protected $_contentf = array(); 	// Folosit pentru Amfw_Search()
	protected $_keywordsf; //keywords field

	public function __construct() {
		$this->__initAll();
	}
	
	public function _initDb() {
		$this->_db =& Amfw_Factory::getDb();
	}
	
	// For calls outside of a dbTable (such as in the algorithm)
	public function db() {
		return $this->_db;
	}

	// Authentication accesibility method for the DbTable class
	// Can be easily overwritten in the children classes
	// Creates and initializes an Authentication adapter
	public function authN($username, $password, $db_table, $username_field, $password_field, $treatment = null )
	{
		if ( !isset( $treatment ))
			$treatment = "'$password'";

		# ??should: Escaping of chars be enforced inside the adapter or credentials should be escaped here (as they are now?)
		$adapter = new Amfw_Authentication();
		$adapter->set('SourceTable',$db_table)
				->set('IdentityCredential', $this->_db->escape($username))
				->set('PasswordCredential', $this->_db->escape($password))
				->set('IdentityField', $username_field)
				->set('PasswordField', $password_field)
				->set('CredentialTreatment', $treatment)
				->processAuthN( $this->_db )
				->saveAuthNResult();

		// The adapter is returned so that optional methods in the adapter can be implemented in the table;
		return $adapter;
	}

	public function load( $id = null ) {
		$vars = get_object_vars($this);
		$tmp = array();

		foreach ($vars as $varName => $value) {
			if( substr($varName,0,1) != '_' )
				$tmp[] = "`".$varName."`";
		}
		
		$where = '1';
		if(isset( $id ))
			$where = "`" . $this->_pk . "` = '" . $id . "'";

		$order 	= Amfw_Request::getv('order',null);
		$sort 	= Amfw_Request::getv('sortOrder',null);
		$limit 	= Amfw_Request::getv('limit',null);
		
		$query = $this->buildSelectQuery($tmp,$where,$order,$sort,$limit);

		$this->_db->setQuery($query);
		$this->_db->query();
		$rows = $this->_db->getAssocList();
		
		if (count( $rows ) == 1)
		{
			$row = $rows[0];
			foreach ($row as $col => $val) 
				$this->$col = $val;
		}

		return $rows;
	}
	
	public function bind( $data ) {
		$vars = get_object_vars($this);
		
		if (!is_object($data))
			$data = (object) $data;
		
		foreach ($vars as $varName => $value) {
			if ( substr($varName,0,1) != '_' ) {
				$this->$varName = @$data->$varName;	//TODO: Este un notice aici, pentru null
			}
		}
		
		return $this;
	}
	
	public function store($db_table = null, $primary_key = null) 
	{ 
		if ( !isset( $primary_key ) )
			$primary_key = $this->_pk;

		if( !isset( $db_table ) )
			$db_table = $this->_table;

		$vars = get_object_vars($this);
		
		$data = array();
		foreach ($vars as $varName => $value) {
			if ( substr($varName,0,1) != '_' ) {
				$data[$varName] = $value;
			}
		}

		// Basically, we're Inserting a new row
		$insertNew = true;
		
		// Checks if the primary key given already has a match in the table
		if(isset( $primary_key ) && isset( $data[$primary_key] )) {
			$query = "SELECT COUNT(*) ";
			$query .= "FROM `$db_table` ";
			$query .= "WHERE `$primary_key`='".$data[$primary_key]."'";
			$this->_db->setQuery($query,true);
			$ans = $this->_db->getRow();

			$insertNew = ( $ans[0] == 0 );
		}

		if( $insertNew ) 
			$query = $this->buildInsertQuery( $data );
		else 
			$query = $this->buildUpdateQuery( $data );

		$this->_db->setQuery($query,true);

	}//store()
	
	public function buildInsertQuery( $data, $db_table = null )
	{
			if( !isset( $db_table ) )
				$db_table = $this->_table;
			
			$cols = '(';
			$vals = '(';
			foreach ($data as $col => $val) {
				$cols .= "`$col`,";
				$vals .= (isset( $val )) ? "'" . $this->_db->escape($val) . "'," : "NULL,";
			}
			$cols = rtrim($cols,', ');
			$vals = rtrim($vals,', ');
			$cols .= ')';
			$vals .= ')';

			$query = "INSERT INTO `$db_table` ";
			$query .= "$cols VALUES $vals";

			return $query;
	}

	public function buildUpdateQuery( $data, $db_table = null, $primary_key = null )
	{
			if ( !isset( $primary_key ) )
				$primary_key = $this->_pk;

			if( !isset( $db_table ) )
				$db_table = $this->_table;
	
			$query = "UPDATE `$db_table` SET ";
			foreach ($data as $col => $val) {
				if(isset( $val ) && $col != $primary_key) {
					$query .= "`$col`='" . $this->_db->escape($val) . "', ";
				}
			}
			$query = rtrim($query,', ');
			$query .= " WHERE `$primary_key` = '" . $data[ $primary_key ] . "'";
	
			return $query;
	}
	
	public function buildSelectQuery ( $cols = '*', $where = '1', $order = null, $sort = null, $limit = null, $db_table = null, $primary_key = null )
	{
		if ( !isset( $primary_key ) )
			$primary_key = $this->_pk;

		if( !isset( $db_table ) )
			$db_table = $this->_table;
			
		if( !isset( $where ) )
			$where = '1';
			
		if ( is_array($cols) )
			$cols = implode(',', $cols);
		
		$query = "SELECT $cols FROM `$db_table` WHERE $where";
		$query .= !empty( $order ) ? " ORDER BY `$order`" : '';
		$query .= !empty( $sort 	) ? " $sort" : '';
		$query .= !empty( $limit ) ? " LIMIT $limit" : '';
		
		return $query;
	}
}